/**
 * 项目名称（软件名称）：忠旺机械物资管理系统(mms)
 * 研发设计单位：忠旺机械设备制造有限公司机械设计院智能控制设计科设计与研发。
 * 版权所有：忠旺机械设备制造有限公司
 * 注：本项目的一切技术专利，使用规范归解释权由忠旺机械设备制造有限公司所有。
 * 软件版本：Ver 1.0.0
 * 文件路径：com.zhongwang.mms.module.purchase.service
 * 创建时间：2020年05月06日 18时05分
 **/
package com.zhongwang.mms.module.purchase.service;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.zhongwang.mms.base.BaseService;
import com.zhongwang.mms.common.JsonResult;
import com.zhongwang.mms.gen.entity.HInventory;
import com.zhongwang.mms.gen.entity.HProjectInventoryMark;
import com.zhongwang.mms.gen.entity.PInventory;
import com.zhongwang.mms.gen.entity.User;
import com.zhongwang.mms.module.basic.dao.TWarehouseInfoDao;
import com.zhongwang.mms.module.half.dao.HalfHInventoryDao;
import com.zhongwang.mms.module.half.model.HProjectInventoryMarkModel;
import com.zhongwang.mms.module.purchase.dao.PurPInventoryDao;
import com.zhongwang.mms.module.purchase.dao.PurProInvDao;
import com.zhongwang.mms.module.purchase.model.proInv.PInventoryModel;
import com.zhongwang.mms.module.purchase.model.proInv.PProjectInventoryMarkModel;
import com.zhongwang.mms.module.system.user.UserDao;
import com.zhongwang.mms.util.FileUtils;
import com.zhongwang.mms.util.ShiroUtils;
import lombok.extern.log4j.Log4j2;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @ClassName： PurProInvService
 * @Description： 项目划库存业务逻辑层
 * @Author： 徐一贺
 * @Date： 2020/5/6 18:05
 * @Version： V1.0
 **/
@Log4j2
@Service
public class PurProInvService extends BaseService {
    @Value("${user.upload.path}")
    private String uploadPath;
    @Autowired
    private PurProInvDao purProInvDao;
    @Autowired
    private PurPInventoryDao purPInventoryDao;
    @Autowired
    private HalfHInventoryDao halfPInventoryDao;
    @Autowired
    private UserDao userDao;
    @Autowired
    private TWarehouseInfoDao tWarehouseInfoDao;

    /**
     * @FunctionName: applyList
     * @Description: 获取项目划库存申请列表
     * @Author: 徐一贺
     * @CreateDate: 2020/5/6 18:26
     * @Phone: 18241927380
     * @Param: [param] 检索条件
     * @Return: com.zhongwang.mms.common.JsonResult 项目划库存申请列表
     * @Version: 1.0.0
     */
    public List<PProjectInventoryMarkModel> applyList(PProjectInventoryMarkModel param) {
        if (param.getEndDate() != null) {
            Calendar cal = Calendar.getInstance();
            cal.setTime(param.getEndDate());
            cal.add(Calendar.DAY_OF_YEAR, 1);
            param.setEndDate(cal.getTime());
        }
        if (param.getEndRemoveDate() != null) {
            Calendar cal = Calendar.getInstance();
            cal.setTime(param.getEndRemoveDate());
            cal.add(Calendar.DAY_OF_YEAR, 1);
            param.setEndRemoveDate(cal.getTime());
        }
        if (param.getEndSubmitDate() != null) {
            Calendar cal = Calendar.getInstance();
            cal.setTime(param.getEndSubmitDate());
            cal.add(Calendar.DAY_OF_YEAR, 1);
            param.setEndSubmitDate(cal.getTime());
        }
        try{
            return purProInvDao.findPProjectInventoryMarkList(param);
        }catch (Exception e){
            e.printStackTrace();
        }
        return purProInvDao.findPProjectInventoryMarkList(param);
    }

    /**
     * @FunctionName: applyInvList
     * @Description: 获取新增项目划库存标记页面库存列表
     * @Author: 徐一贺
     * @CreateDate: 2020/5/6 19:34
     * @Phone: 18241927380
     * @Param: [param] 检索条件
     * @Return: com.zhongwang.mms.common.JsonResult 项目划库存标记页面库存列表
     * @Version: 1.0.0
     */
    public List<PInventoryModel> applyInvList(PInventoryModel param) {
        return purPInventoryDao.findInventoryByProInv(param);
    }

    /**
     * @FunctionName: applyGetInventory
     * @Description: 根据主键和仓库类型获取库存信息
     * @Author: 徐一贺
     * @CreateDate: 2020/5/8 9:47
     * @Phone: 18241927380
     * @Param: [param.ityId] 主键、[param.ityType] p是外购件库，h是成品库，m是原料库
     * @Return: [PProjectInventoryMarkModel] 库存信息
     * @Version: 1.0.0
     */
    public PProjectInventoryMarkModel applyGetInventory(PProjectInventoryMarkModel param) {
        switch (param.getPimItyType()) {
            case "p":
                return purPInventoryDao.getPInventoryByPrimaryKey(param.getPimBeforeItyId());
            case "h":
                return purPInventoryDao.getHInventoryByPrimaryKey(param.getPimBeforeItyId());
            case "m":
                return purPInventoryDao.getMInventoryByPrimaryKey(param.getPimBeforeItyId());
            default:
                return null;
        }
    }

    /**
     * @FunctionName: applyMark
     * @Description: 创建标记
     * @Author: 徐一贺
     * @CreateDate: 2020/5/8 10:32
     * @Phone: 18241927380
     * @Param: [param] 被标记的库存信息
     * @Return: [JsonResult] 标记结果
     * @Version: 1.0.0
     */
    @Transactional(rollbackFor = Exception.class)
    public JsonResult applyMark(PProjectInventoryMarkModel param) {
        JsonResult jsonResult = new JsonResult();
        try {
            PInventory pInventory = purPInventoryDao.findByPrimaryKey(param.getPimBeforeItyId());
            if (pInventory.getItyAvaNum() < param.getPimNum()) {
                jsonResult.setType(JsonResult.ResultType.ERROR);
                jsonResult.setMsg("当前选取的库存中物料名称为：【" + pInventory.getItyMatDesc() + "】的物料因可用数量不足，而导致此次标记失败！");
                return jsonResult;
            }
            param.setPimProposerId(ShiroUtils.getUser().getId());
            param.setPimDate(new Date());
            param.setPimMatCode(param.getPimSapCode());
            param.setPimAppStatus(1);
            purProInvDao.insertPProjectInventoryMarkBySelective(param);
            PInventory changeItyAnaNumModel = new PInventory();
            changeItyAnaNumModel.setItyId(pInventory.getItyId());
            pInventory.setItyAvaNum(pInventory.getItyAvaNum() - param.getPimNum());
            purPInventoryDao.updateByPrimaryKeySelective(pInventory);
            jsonResult.setType(JsonResult.ResultType.SUCCESS);
            jsonResult.setMsg("标记成功！");
            logService.saveLog("【外购件】项目划库存", "标记成功，被标记的物料名称是：" + param.getPimMatDesc() + "，所属的项目的项目编号是：" + param.getPimBeforeProCode() + ",标记数量为：" + param.getPimNum());
        } catch (Exception e) {
            e.printStackTrace();
            log.error(e.getMessage());
            jsonResult.setType(JsonResult.ResultType.ERROR);
            jsonResult.setMsg("标记失败！");
        }
        return jsonResult;
    }

    /**
     * @FunctionName: applySaveMarks
     * @Description: 编辑标记
     * @Author: 徐一贺
     * @CreateDate: 2020/5/8 10:32
     * @Phone: 18241927380
     * @Param: [param] 被标记的库存信息
     * @Return: [JsonResult] 标记结果
     * @Version: 1.0.0
     */
    @Transactional(rollbackFor = Exception.class)
    public JsonResult applySaveMarks(PProjectInventoryMarkModel param) {
        JsonResult jsonResult = new JsonResult();
        try {
            PProjectInventoryMarkModel sourcePProjectInventoryMarkModel = purProInvDao.getPProjectInventoryMarkModelByPrimaryKey(param.getPimId());
            PInventory pInventory = purPInventoryDao.findByPrimaryKey(param.getPimBeforeItyId());
            if ((pInventory.getItyAvaNum() + sourcePProjectInventoryMarkModel.getPimNum()) < param.getPimNum()) {
                jsonResult.setType(JsonResult.ResultType.ERROR);
                jsonResult.setMsg("当前选取的库存中物料名称为：【" + pInventory.getItyMatDesc() + "】的物料因可用数量不足，而导致此次标记失败！");
                return jsonResult;
            }
            PProjectInventoryMarkModel updatePProjectInventoryMarkModel = new PProjectInventoryMarkModel();
            PProjectInventoryMarkModel source = purProInvDao.getPProjectInventoryMarkModelByPrimaryKey(param.getPimId());
            updatePProjectInventoryMarkModel.setPimId(param.getPimId());
            updatePProjectInventoryMarkModel.setPimNum(param.getPimNum());
            updatePProjectInventoryMarkModel.setPimRemark(param.getPimRemark());
            if (param.getPimAppStatus().equals(2)) {
                updatePProjectInventoryMarkModel.setPimAppStatus(1);
            }
            PInventory changeItyAnaNumModel = new PInventory();
            changeItyAnaNumModel.setItyId(pInventory.getItyId());
            pInventory.setItyAvaNum(pInventory.getItyAvaNum() + source.getPimNum() - updatePProjectInventoryMarkModel.getPimNum());
            purPInventoryDao.updateByPrimaryKeySelective(pInventory);


            purProInvDao.updateSelectiveByPrimaryKey(updatePProjectInventoryMarkModel);
            jsonResult.setType(JsonResult.ResultType.SUCCESS);
            jsonResult.setMsg("标记成功！");
            logService.saveLog("【外购件】项目划库存", "标记成功，被标记的物料名称是：" + param.getPimMatDesc() + "，所属的项目的项目编号是：" + param.getPimBeforeProCode() + ",标记数量为：" + param.getPimNum());
        } catch (Exception e) {
            e.printStackTrace();
            log.error(e.getMessage());
            jsonResult.setType(JsonResult.ResultType.ERROR);
            jsonResult.setMsg("标记失败！");
        }
        return jsonResult;
    }

    @Transactional(rollbackFor = Exception.class)
    /**
     *@FunctionName: applyMarkS
     *@Description: 批量标记
     *@Author: 徐一贺
     *@CreateDate: 2020/5/8 11:26
     *@Phone: 18241927380
     *@Param: [param]
     *@Return: com.zhongwang.mms.common.JsonResult
     *@Version: 1.0.0
     */
    public JsonResult applyMarks(List<PProjectInventoryMarkModel> param) {
        JsonResult jsonResult = new JsonResult();
        try {
            for (PProjectInventoryMarkModel pProjectInventoryMarkModel : param) {
                //如果是外购件库
                if (pProjectInventoryMarkModel.getPimItyType().equals("p")) {
                    PInventory pInventory = purPInventoryDao.findByPrimaryKey(pProjectInventoryMarkModel.getPimBeforeItyId());
                    if (pInventory.getItyAvaNum() <= 0) {
                        jsonResult.setType(JsonResult.ResultType.ERROR);
                        jsonResult.setMsg("批量选取的库存中其中物料名称为：【" + pInventory.getItyMatDesc() + "】的物料因可用数量不足，而导致此次批量标记失败！");
                        return jsonResult;
                    }
                }
                //如果是成品库
                else if (pProjectInventoryMarkModel.getPimItyType().equals("h")) {
                    HInventory hInventory = halfPInventoryDao.findHInventoryByPrimaryKey(pProjectInventoryMarkModel.getPimBeforeItyId());
                    if (hInventory.getItyAvaNum() <= 0 && hInventory.getItyAvaWeight() <= 0) {
                        jsonResult.setType(JsonResult.ResultType.ERROR);
                        jsonResult.setMsg("批量选取的库存中其中物料名称为：【" + hInventory.getItyMatName() + "】的物料因可用数量不足，而导致此次批量标记失败！");
                        return jsonResult;
                    }
                }
            }
            for (PProjectInventoryMarkModel pProjectInventoryMarkModel : param) {
                //如果是外购件库
                if (pProjectInventoryMarkModel.getPimItyType().equals("p")) {
                    PInventory pInventory = purPInventoryDao.findByPrimaryKey(pProjectInventoryMarkModel.getPimBeforeItyId());
                    pProjectInventoryMarkModel.setPimMatDesc(pInventory.getItyMatDesc());
                    pProjectInventoryMarkModel.setPimSapCode(pInventory.getItySapCode());
                    pProjectInventoryMarkModel.setPimMatCode(pInventory.getItySapCode());
                    pProjectInventoryMarkModel.setPimBeforeProCode(pInventory.getItyProCode());
                    pProjectInventoryMarkModel.setPimBeforeProName(pInventory.getItyProName());
                    pProjectInventoryMarkModel.setPimNum(pInventory.getItyAvaNum());
                    pProjectInventoryMarkModel.setPimProposerId(ShiroUtils.getUser().getId());
                    pProjectInventoryMarkModel.setPimDate(new Date());
                    pProjectInventoryMarkModel.setPimAppStatus(1);
                    purProInvDao.insertPProjectInventoryMarkBySelective(pProjectInventoryMarkModel);
                    PInventory changeItyAnaNumModel = new PInventory();
                    changeItyAnaNumModel.setItyId(pInventory.getItyId());
                    pInventory.setItyAvaNum(pInventory.getItyAvaNum() - pProjectInventoryMarkModel.getPimNum());
                    purPInventoryDao.updateByPrimaryKeySelective(pInventory);
                    logService.saveLog("【外购件】项目划库存", "标记成功，被标记的物料名称是：" + pInventory.getItyMatDesc() + "，所属的项目的项目编号是：" + pInventory.getItyProCode() + ",标记数量为：" + pProjectInventoryMarkModel.getPimNum());
                }
                //如果是成品库
                else if (pProjectInventoryMarkModel.getPimItyType().equals("h")) {
                    HInventory hInventory = halfPInventoryDao.findHInventoryByPrimaryKey(pProjectInventoryMarkModel.getPimBeforeItyId());
                    HProjectInventoryMarkModel hProjectInventoryMarkModel = new HProjectInventoryMarkModel();
                    hProjectInventoryMarkModel.setPimBeforeItyId(hInventory.getItyId());
                    hProjectInventoryMarkModel.setPimBeforeProName(hInventory.getItyProName());
                    hProjectInventoryMarkModel.setPimBeforeProCode(hInventory.getItyProCode());
                    hProjectInventoryMarkModel.setPimSapCode(hInventory.getItySapCode());
                    hProjectInventoryMarkModel.setPimMatCode(hInventory.getItySapCode());
                    hProjectInventoryMarkModel.setPimNum(hInventory.getItyNum());
                    hProjectInventoryMarkModel.setPimNumUnit(hInventory.getItyUnit());
                    hProjectInventoryMarkModel.setPimWeight(hInventory.getItyWeight());
                    hProjectInventoryMarkModel.setPimMatDesc(hInventory.getItyMatName());
                    hProjectInventoryMarkModel.setPimRemark("批量项目划库存");
                    hProjectInventoryMarkModel.setPimProposerId(ShiroUtils.getUser().getId());
                    hProjectInventoryMarkModel.setPimDate(new Date());
                    hProjectInventoryMarkModel.setPimAppStatus(1);
                    halfPInventoryDao.insertHProjectInventoryMarkBySelective(hProjectInventoryMarkModel);
                    HInventory changeItyAnaNumModel = new HInventory();
                    changeItyAnaNumModel.setItyId(hInventory.getItyId());
                    if (hInventory.getItyNum() != null && hInventory.getItyAvaNum() != null) {
                        changeItyAnaNumModel.setItyAvaNum(hInventory.getItyAvaNum() - hProjectInventoryMarkModel.getPimNum());
                    }
                    if (hInventory.getItyWeight() != null && hInventory.getItyAvaWeight() != null) {
                        changeItyAnaNumModel.setItyAvaWeight(hInventory.getItyAvaWeight() - hProjectInventoryMarkModel.getPimWeight());
                    }
                    halfPInventoryDao.updateByPrimaryKeySelective(changeItyAnaNumModel);
                    logService.saveLog("【成品库】项目划库存", "标记成功，被标记的物料名称是：" + hInventory.getItyMatName() + "，所属的项目的项目编号是：" + hInventory.getItyProCode() + ",标记数量为：" + pProjectInventoryMarkModel.getPimNum());
                }
            }
            jsonResult.setType(JsonResult.ResultType.SUCCESS);
            jsonResult.setMsg("标记成功！");
        } catch (Exception e) {
            e.printStackTrace();
            log.error(e.getMessage());
            jsonResult.setType(JsonResult.ResultType.ERROR);
            jsonResult.setMsg("标记失败！");
        }
        return jsonResult;
    }

    /**
     * @FunctionName: applyRemove
     * @Description: 批量删除
     * @Author: 徐一贺
     * @CreateDate: 2020/5/8 13:26
     * @Phone: 18241927380
     * @Param: [param]
     * @Return: com.zhongwang.mms.common.JsonResult
     * @Version: 1.0.0
     */
    @Transactional(rollbackFor = Exception.class)
    public JsonResult applyRemove(PProjectInventoryMarkModel param) {
        JsonResult jsonResult = new JsonResult();
        try {
            List<PProjectInventoryMarkModel> pProjectInventoryMarkModelList = purProInvDao.findPimAppStatusByPrimaryKeys(param.getPimIds());
            for (PProjectInventoryMarkModel pProjectInventoryMarkModel : pProjectInventoryMarkModelList) {
                PInventory pInventory = purPInventoryDao.findByPrimaryKey(pProjectInventoryMarkModel.getPimBeforeItyId());
                PInventory changeItyAnaNumModel = new PInventory();
                changeItyAnaNumModel.setItyId(pProjectInventoryMarkModel.getPimBeforeItyId());
                pInventory.setItyAvaNum(pInventory.getItyAvaNum() + pProjectInventoryMarkModel.getPimNum());
                if (pInventory.getItyAvaNum() <= pInventory.getItyNum()) {
                    purPInventoryDao.updateByPrimaryKeySelective(pInventory);
                }
            }
            param.setPimRemoveUserId(ShiroUtils.getUserId());
            param.setPimRemoveDate(getDateTimeService.getSysDateTime());
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
            param.setPimRemoveDateStr(sdf.format(param.getPimRemoveDate()));
            purProInvDao.deleteByPrimaryKeys(param);
            jsonResult.setType(JsonResult.ResultType.SUCCESS);
            jsonResult.setMsg("删除标记成功！");
            logService.saveLog("【外购件】项目划库存", "删除标记");
        } catch (Exception e) {
            e.printStackTrace();
            log.error(e.getMessage());
            jsonResult.setType(JsonResult.ResultType.ERROR);
            jsonResult.setMsg("删除标记失败！");
        }
        return jsonResult;
    }

    /**
     * @FunctionName: applySubmit
     * @Description: 批量提交
     * @Author: 徐一贺
     * @CreateDate: 2020/5/8 13:44
     * @Phone: 18241927380
     * @Param: [param]
     * @Return: com.zhongwang.mms.common.JsonResult
     * @Version: 1.0.0
     */
    @Transactional(rollbackFor = Exception.class)
    public JsonResult applySubmit(PProjectInventoryMarkModel param) {
        JsonResult jsonResult = new JsonResult();
        try {
            Date currentTime = new Date();
            param.setPimAppStatus(3);
            param.setPimSubmitDate(currentTime);
            purProInvDao.updatePimAppStatusByPrimaryKeys(param);
            jsonResult.setType(JsonResult.ResultType.SUCCESS);
            jsonResult.setMsg("批量提交成功！");
            logService.saveLog("【外购件】项目划库存", "提交申请成功！");
        } catch (Exception e) {
            e.printStackTrace();
            log.error(e.getMessage());
            jsonResult.setType(JsonResult.ResultType.ERROR);
            jsonResult.setMsg("批量提交失败！");
        }
        return jsonResult;
    }

    /**
     * @FunctionName: applyGetPProjectInventoryMark
     * @Description: 根据主键获取项目化库存
     * @Author: 徐一贺
     * @CreateDate: 2020/5/8 14:16
     * @Phone: 18241927380
     * @Param: [param]
     * @Return: com.zhongwang.mms.common.JsonResult
     * @Version: 1.0.0
     */
    public JsonResult getPProjectInventoryMark(PProjectInventoryMarkModel param) {
        JsonResult jsonResult = new JsonResult();
        try {
            PProjectInventoryMarkModel pProjectInventoryMarkModel = purProInvDao.getPProjectInventoryMarkModelByPrimaryKey(param.getPimId());
            pProjectInventoryMarkModel.setPimBeforeAvaNum(pProjectInventoryMarkModel.getPimNum() + purPInventoryDao.getInventoryByPrimaryKey(pProjectInventoryMarkModel.getPimBeforeItyId()).getItyAvaNum());
            jsonResult.setType(JsonResult.ResultType.SUCCESS);
            jsonResult.setData(pProjectInventoryMarkModel);
            jsonResult.setMsg("获取成功！");
        } catch (Exception e) {
            e.printStackTrace();
            log.error(e.getMessage());
            jsonResult.setType(JsonResult.ResultType.ERROR);
            jsonResult.setMsg("获取失败！");
        }
        return jsonResult;
    }

    /**
     * @FunctionName: reviewList
     * @Description: 审核列表
     * @Author: 徐一贺
     * @CreateDate: 2020/5/8 15:28
     * @Phone: 18241927380
     * @Param: [param] 检索条件
     * @Return: com.zhongwang.mms.common.JsonResult 项目划库存申请列表
     * @Version: 1.0.0
     */
    public List<PProjectInventoryMarkModel> reviewList(PProjectInventoryMarkModel param) {
        if (param.getEndDate() != null) {
            Calendar cal = Calendar.getInstance();
            cal.setTime(param.getEndDate());
            cal.add(Calendar.DAY_OF_YEAR, 1);
            param.setEndDate(cal.getTime());
        }
        if (param.getPimExecEndDate() != null) {
            Calendar cal = Calendar.getInstance();
            cal.setTime(param.getPimExecEndDate());
            cal.add(Calendar.DAY_OF_YEAR, 1);
            param.setPimExecEndDate(cal.getTime());
        }if (param.getEndSubmitDate() != null) {
            Calendar cal = Calendar.getInstance();
            cal.setTime(param.getEndSubmitDate());
            cal.add(Calendar.DAY_OF_YEAR, 1);
            param.setEndSubmitDate(cal.getTime());
        }
        return purProInvDao.findReviewListList(param);
    }

    /**
     * @FunctionName: reviewReject
     * @Description: 审核驳回
     * @Author: 徐一贺
     * @CreateDate: 2020/5/8 15:53
     * @Phone: 18241927380
     * @Param: [param.pimIds] 被驳回的主键们
     * @Return: [JsonResult] 驳回结果
     * @Version: 1.0.0
     */
    @Transactional(rollbackFor = Exception.class)
    public JsonResult reviewReject(PProjectInventoryMarkModel param) {
        JsonResult jsonResult = new JsonResult();
        try {
            List<String> errorList = new ArrayList<>();
            List<PProjectInventoryMarkModel> logPProjectInventoryMarkModels = purProInvDao.getPProjectInventoryMarkModelByPrimaryKeys(param.getPimIds());
            for (PProjectInventoryMarkModel logPProjectInventoryMarkModel:logPProjectInventoryMarkModels ) {
                PInventory pInventory = purProInvDao.getPInventoryByPrimaryKey(logPProjectInventoryMarkModel.getPimBeforeItyId());
                if(logPProjectInventoryMarkModel.getPimAppStatus()==3){
                    logPProjectInventoryMarkModel.setPimAppStatus(2);
                    logPProjectInventoryMarkModel.setPimRejectReaso(param.getPimRejectReaso());
                    purProInvDao.updatePimAppStatusByPrimaryKey(logPProjectInventoryMarkModel);
                    User user = userDao.findUserById(logPProjectInventoryMarkModel.getPimProposerId());
                    logService.saveLog("【外购件】项划库存执行驳回操作", "驳回" + user.getName() + "的物料名称为：" + pInventory.getItyMatDesc() + "的申请");
                }else{
                    errorList.add("物料名称为："+ pInventory.getItyMatDesc() + "的申请已执行或已驳回无法再次驳回。<br>");
                }
            }
            if(errorList.size()>0){
                jsonResult.setType(JsonResult.ResultType.ERROR);
                jsonResult.setMsg(errorList.toString());
            }else{
                jsonResult.setType(JsonResult.ResultType.SUCCESS);
                jsonResult.setMsg("驳回成功！");
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error(e.getMessage());
            jsonResult.setType(JsonResult.ResultType.ERROR);
            jsonResult.setMsg("驳回失败！");
        }
        return jsonResult;
    }

    /**
     * @FunctionName: reviewExec
     * @Description: 执行
     * @Author: 徐一贺
     * @CreateDate: 2020/5/8 16:38
     * @Phone: 18241927380
     * @Param: [param]
     * @Return: com.zhongwang.mms.common.JsonResult
     * @Version: 1.0.0
     */
    @Transactional(rollbackFor = Exception.class)
    public JsonResult reviewExec(PProjectInventoryMarkModel param) {
        JsonResult jsonResult = new JsonResult();
        try {
            List<PProjectInventoryMarkModel> projectInventoryMarkModelList = purProInvDao.findPimAppStatusByPrimaryKeys(param.getPimIds());
            List<String> errorList = new ArrayList<>();
            //检测在库数量是否可以执行
            for (PProjectInventoryMarkModel projectInventoryMarkModel : projectInventoryMarkModelList) {
                PInventory pInventory = purPInventoryDao.findByPrimaryKey(projectInventoryMarkModel.getPimBeforeItyId());
                if(projectInventoryMarkModel.getPimAppStatus()==3){
                    //外购件库
                    if (projectInventoryMarkModel.getPimItyType().equals("p")) {
                        if (pInventory.getItyNum() < projectInventoryMarkModel.getPimNum()) {
                            errorList.add("执行的项目划库存申请中其中物料描述为：【" + pInventory.getItyMatDesc() + "】的物料因库存数量不符合要求，请驳回该申请！<br>");
                        } else {
                            //外购件库
                            if (projectInventoryMarkModel.getPimItyType().equals("p")) {
                                //PInventory pInventory = purPInventoryDao.findByPrimaryKey(projectInventoryMarkModel.getPimBeforeItyId());
                                if (pInventory.getItyNum() < projectInventoryMarkModel.getPimNum()) {
                                    throw new Exception("执行的项目划库存申请中其中物料名称为：【" + pInventory.getItyMatDesc() + "】的物料因库存数量不符合要求。");
                                } else {
                                    PInventory changeItyNumModel = new PInventory();
                                    changeItyNumModel.setItyId(pInventory.getItyId());
                                    changeItyNumModel.setItyNum(pInventory.getItyNum() - projectInventoryMarkModel.getPimNum());
                                    //更改原库存
                                    if (pInventory.getItyProInvFlag() == null || pInventory.getItyProInvFlag().equals(0)) {
                                        changeItyNumModel.setItyProInvFlag(2);
                                    } else if (changeItyNumModel.getItyProInvFlag().equals(1)) {
                                        changeItyNumModel.setItyProInvFlag(3);
                                    }
                                    purPInventoryDao.updateByPrimaryKeySelective(changeItyNumModel);
                                    pInventory.setItyNum(projectInventoryMarkModel.getPimNum());
                                    pInventory.setItyAvaNum(projectInventoryMarkModel.getPimNum());
                                    pInventory.setItyStockType(1);
//                                    if (tWarehouseInfoDao.getTWarehouseInfoByWhiId(pInventory.getItyWhiId()).getWhiCode().equals("机械备件库")) {
//                                        pInventory.setItyProName("");
//                                        pInventory.setItyProCode("");
//                                    }
                                    //插入新库存
                                    pInventory.setItyProInvFlag(1);
                                    purPInventoryDao.insertSelective(pInventory);

                                    PProjectInventoryMarkModel changePimAppStatus = new PProjectInventoryMarkModel();
                                    changePimAppStatus.setPimId(projectInventoryMarkModel.getPimId());
                                    changePimAppStatus.setPimAppStatus(4);
                                    changePimAppStatus.setPimAfterItyId(pInventory.getItyId());
                                    changePimAppStatus.setPimExecutorId(ShiroUtils.getUser().getId());
                                    changePimAppStatus.setPimExecDate(new Date());
                                    changePimAppStatus.setPimPrice(pInventory.getItyPrice());
                                    //回写项目划库存状态为已执行并标记生成后的新的库存信息，以用于撤销使用。
                                    purProInvDao.updateSelectiveByPrimaryKey(changePimAppStatus);
                                    //记录操作日志
                                    logService.saveLog("【外购件库】项目化库存执行", "被执行的物料名称：" + pInventory.getItyMatDesc() + ",所属项目编号：" + pInventory.getItyProCode());
                                }
                            }
                        }
                    }
                }else{
                    errorList.add("执行的项目划库存申请中其中物料描述为：【" + pInventory.getItyMatDesc() + "】的物料的申请已经执行或驳回，无法再次执行！<br>");
                }
            }
            if (errorList.size() > 0) {
                jsonResult.setType(JsonResult.ResultType.ERROR);
                jsonResult.setMsg(errorList.toString());
                return jsonResult;
            }
            //设置返回内容
            jsonResult.setType(JsonResult.ResultType.SUCCESS);
            jsonResult.setMsg("执行成功！");
        } catch (Exception e) {
            e.printStackTrace();
            log.error(e.getMessage());
            //设置返回内容
            jsonResult.setType(JsonResult.ResultType.ERROR);
            jsonResult.setMsg("执行失败！");
        }
        return jsonResult;
    }

    /**
     * @FunctionName: reviewRevoke
     * @Description: 撤销
     * @Author: 徐一贺
     * @CreateDate: 2020/5/8 16:38
     * @Phone: 18241927380
     * @Param: [param]
     * @Return: com.zhongwang.mms.common.JsonResult
     * @Version: 1.0.0
     */
    @Transactional(rollbackFor = Exception.class)
    public JsonResult reviewRevoke(PProjectInventoryMarkModel param) {
        JsonResult jsonResult = new JsonResult();
        try {
            //获取撤销列表
            List<PProjectInventoryMarkModel> projectInventoryMarkModelList = purProInvDao.findPimAppStatusByPrimaryKeys(param.getPimIds());
            //检测在库数量是否可以撤销
            for (PProjectInventoryMarkModel projectInventoryMarkModel : projectInventoryMarkModelList) {
                //外购件库
                if (projectInventoryMarkModel.getPimItyType().equals("p")) {
                    //获取撤销的库存对象
                    PInventory pInventory = purPInventoryDao.findByPrimaryKey(projectInventoryMarkModel.getPimAfterItyId());
                    if (pInventory.getItyNum() < projectInventoryMarkModel.getPimNum()) {
                        jsonResult.setType(JsonResult.ResultType.ERROR);
                        jsonResult.setMsg("撤销的项目划库存申请中其中物料名称为：【" + pInventory.getItyMatDesc() + "】的物料因库存数量不符合要求，不可执行撤销！");
                        return jsonResult;
                    }
                    if (pInventory.getItyAvaNum() < projectInventoryMarkModel.getPimNum()) {
                        jsonResult.setType(JsonResult.ResultType.ERROR);
                        jsonResult.setMsg("撤销的项目划库存申请中其中物料名称为：【" + pInventory.getItyMatDesc() + "】的物料因可用数量不符合要求，不可执行撤销！");
                        return jsonResult;
                    }
                }
            }
            //循环执行
            for (PProjectInventoryMarkModel projectInventoryMarkModel : projectInventoryMarkModelList) {
                //外购件库
                if (projectInventoryMarkModel.getPimItyType().equals("p")) {
                    //获取撤销的库存对象
                    PInventory pInventory = purPInventoryDao.findByPrimaryKey(projectInventoryMarkModel.getPimAfterItyId());
                    if (pInventory.getItyNum() < projectInventoryMarkModel.getPimNum()) {
                        throw new Exception("撤销的项目划库存申请中其中物料名称为：【" + pInventory.getItyMatDesc() + "】的物料因库存数量不符合要求。");
                    } else if (pInventory.getItyAvaNum() < projectInventoryMarkModel.getPimNum()) {
                        throw new Exception("撤销的项目划库存申请中其中物料名称为：【" + pInventory.getItyMatDesc() + "】的物料因库存数量不符合要求。");
                    } else {
                        //记录操作日志
                        logService.saveLog("【外购件库】项目化库存撤销", "被撤销的物料名称：" + pInventory.getItyMatDesc() + ",所属项目编号：" + pInventory.getItyProCode());
                        //减去因执行新生成的库存数量
                        PInventory changeNumAndAvaNumModel = new PInventory();
                        changeNumAndAvaNumModel.setItyId(pInventory.getItyId());
                        changeNumAndAvaNumModel.setItyNum(pInventory.getItyNum() - projectInventoryMarkModel.getPimNum());
                        changeNumAndAvaNumModel.setItyAvaNum(pInventory.getItyAvaNum() - projectInventoryMarkModel.getPimNum());
                        changeNumAndAvaNumModel.setItyInvProFlag(0);
                        //更新因执行新生成的库存数据
                        purPInventoryDao.updateByPrimaryKeySelective(changeNumAndAvaNumModel);

                        //回写状态
                        PProjectInventoryMarkModel changePimAppStatus = new PProjectInventoryMarkModel();
                        changePimAppStatus.setPimId(projectInventoryMarkModel.getPimId());
                        changePimAppStatus.setPimAfterItyId(null);
                        changePimAppStatus.setPimAppStatus(3);
                        changePimAppStatus.setPimExecutorId(null);
                        changePimAppStatus.setPimExecDate(null);
                        //回写项目划库存状态为未执行。
                        purProInvDao.updateSelectiveByPrimaryKeyNotHavePimAfterItyId(changePimAppStatus);
                        //增加被执行的库存的数量
                        pInventory = purPInventoryDao.findByPrimaryKey(projectInventoryMarkModel.getPimBeforeItyId());
                        changeNumAndAvaNumModel.setItyId(pInventory.getItyId());
                        changeNumAndAvaNumModel.setItyNum(pInventory.getItyNum() + projectInventoryMarkModel.getPimNum());
                        changeNumAndAvaNumModel.setItyAvaNum(pInventory.getItyAvaNum());
                        Integer count = purProInvDao.getInvProCountByPimBeforeItyId(projectInventoryMarkModel.getPimBeforeItyId());
                        if (pInventory.getItyInvProFlag() !=null && pInventory.getItyInvProFlag().equals(3) && count == 0) {
                            changeNumAndAvaNumModel.setItyInvProFlag(1);
                        } else if (count == 0) {
                            changeNumAndAvaNumModel.setItyInvProFlag(0);
                        }
                        //反向更新被执行的库存的数量
                        purPInventoryDao.updateByPrimaryKeySelective(changeNumAndAvaNumModel);
                    }
                }
            }
            //设置返回内容
            jsonResult.setType(JsonResult.ResultType.SUCCESS);
            jsonResult.setMsg("撤销成功！");
        } catch (Exception e) {
            e.printStackTrace();
            log.error(e.getMessage());
            //设置返回内容
            jsonResult.setType(JsonResult.ResultType.ERROR);
            jsonResult.setMsg("撤销失败！");
        }
        return jsonResult;
    }

    /**
     * @FunctionName: exportExcelReviewList
     * @Description: 导出执行列表
     * @DesignIdea: 导出执行列表
     * @Author: 徐一贺
     * @CreateDate: 2020/7/1 16:59
     * @Phone: 18241927380
     * @Param:
     * @Return:
     * @Throw:
     * @Version: v 1.0.0
     */
    public void exportExcelReviewList(HttpServletResponse response, PProjectInventoryMarkModel param) {
        if (param.getEndDate() != null) {
            Calendar cal = Calendar.getInstance();
            cal.setTime(param.getEndDate());
            cal.add(Calendar.DAY_OF_YEAR, 1);
            param.setEndDate(cal.getTime());
        }
        if (param.getPimExecEndDate() != null) {
            Calendar cal = Calendar.getInstance();
            cal.setTime(param.getPimExecEndDate());
            cal.add(Calendar.DAY_OF_YEAR, 1);
            param.setPimExecEndDate(cal.getTime());
        }
        List<PProjectInventoryMarkModel> list = new ArrayList<>();
        User user = (User) SecurityUtils.getSubject().getPrincipal();
        String path = uploadPath + user.getAccount() + "/";
        Subject userSubject = ShiroUtils.getSubject();
        //1.创建临时内存表名
        String tempTableName = "##" + ShiroUtils.getUser().getAccount() + (UUID.randomUUID().toString().replace("-", ""));
        param.setTempTableName(tempTableName);
        //2.查询出数据导入到临时表
        purProInvDao.createProInvTempTable(param);
        //3.查询临时内存表数据导出
        Integer dataCount = purProInvDao.getProInvTempTableDataCount(param);
        int step = 5000;
        FileUtils.mkdirs(path);
        // 方法1 如果写到同一个sheet
        path = path + "外购件库库存查询列表.xlsx";
        ExcelWriter excelWriter = null;
        try {
            // 这里 需要指定写用哪个class去写
            excelWriter = EasyExcel.write(path, PProjectInventoryMarkModel.class).build();
            // 这里注意 如果同一个sheet只要创建一次
            WriteSheet writeSheet = EasyExcel.writerSheet("sheet1").build();
            for (int topCount = 5000, notHaveTopCount = 0; notHaveTopCount < dataCount; notHaveTopCount += step) {
                param.setTopCount(topCount);
                param.setNotHaveTopCount(notHaveTopCount);
                list = purProInvDao.selectProInvTempTableByParam(param);
                if (list != null) {
                    excelWriter.write(list, writeSheet);
                }
            }
            //4.删除临时内存表
            purProInvDao.dropProInvTempTable(tempTableName);
        } finally {
            // 千万别忘记finish 会帮忙关闭流
            if (excelWriter != null) {
                excelWriter.finish();
            }
        }
        //5.下载
        FileUtils.downloadFile(path, response);
    }
}